import pickle
import base64
from django_redis import get_redis_connection


def merge_cart_cookie_to_redis(request, user, response):
    """
    合并请求用户的购物车数据，将未登录保存在cookie里的保存到redis中
    遇到cookie与redis中出现相同的商品时以cookie数据为主，覆盖redis中的数据
    :param request: 用户请求的对象
    :param user: 当前登陆的对象
    :param response: 响应对象,用于清除购物车的cookie
    :return:
    """
    cart_cookie = request.COOKIES.get('cart')
    if not cart_cookie:
        return response
    cart_dict = pickle.loads(base64.b64decode(cart_cookie.encode()))
    count_dict = {}
    redis_conn = get_redis_connection('cart')
    redis_cart = redis_conn.hgetall('cart_%s' % user.id)
    for sku_id, count in redis_cart.items():
        # 这里转换成整型的目的是为了和下面从cookie中取出的数据进行合并时使用
        count_dict[int(sku_id)] = int(count)
    selected_add = []
    selected_rem = []
    for sku_id, count_selected_dict in cart_dict.items():
        count_dict[sku_id] = count_selected_dict['count']
        if count_selected_dict['selected']:
            selected_add.append(sku_id)
        else:
            selected_rem.append(sku_id)
    if count_dict:
        redis_conn = get_redis_connection('cart')
        pl = redis_conn.pipeline()
        # hmset此命令会覆盖哈希表中已存在的域,所以才有了上面先从redis取出数据
        pl.hmset('cart_%s' % user.id, count_dict)
        # 下面判断是否为空的原因是避免srem和sadd处理空值的时候报错
        if selected_rem:
            pl.srem('cart_selected_%s' % user.id, *selected_rem)
        if selected_add:
            pl.sadd('cart_selected_%s' % user.id, *selected_add)
        pl.execute()
    response.delete_cookie('cart')
    return response

